package zdream.pmfield.stage.buff.foe;

import java.util.Objects;

import zdream.pmfield.data.foe.MoveType;
import zdream.pmfield.data.foe.Type;
import zdream.pmfield.stage.buff.ailment.AcidBuff;
import zdream.pmfield.stage.buff.ailment.BurnBuff;
import zdream.pmfield.stage.buff.ailment.FrostbiteBuff;
import zdream.pmfield.stage.buff.ailment.ParalysisBuff;
import zdream.pmfield.stage.buff.ailment.WetBuff;
import zdream.pmfield.stage.buff.disease.PoisonedBuff;
import zdream.pmfield.stage.director.AttackContext;
import zdream.pmfield.stage.director.HookType;
import zdream.pmfield.stage.director.Hooks;
import zdream.pmfield.stage.object.FoeActor;
import zdream.pmfield.stage.object.StageMove;

/**
 * <p>TypeBuff 主要工作有:
 * <li>防止 Foe 增加两个相同的属性;
 * <li>属性免疫效果, 包括火防烧伤、电防麻痹、水防潮湿、草防花粉、冰防冰冻、钢防毒
 * <li>使用同属性的技能有本系加成. 这里的本系加成是多个判定骰子
 * </li>
 * </p>
 *
 * @author Zdream
 * @date 2023-11-21
 * @since 0.0.1
 */
public class TypeBuff extends FoeStageBuff {
	public final Type type;
	public static final String CATEGORY = Type.TYPE;

	public TypeBuff(FoeActor foe, Type type) {
		super(foe);
		this.type = Objects.requireNonNull(type);
	}

	@Override
	public void init() {
		onHook(HookType.BEFORE_ATTACK_ROLL_CHECK)
				.handle(this::beforeRollCheck)
				.buildAndSave();
		onHook(HookType.BEFORE_FOE_RECEIVE_BUFF)
				.handle(this::beforeFoeReceiveBuff)
				.buildAndSave();
	}

	/**
	 * 本系加成 (Same-Type attack bonus): 凭空创造出一个判定骰子. 麻痹时失效
	 * 优先度较高
	 */
	private void beforeRollCheck(Hooks.HookContext rawContext) {
		final boolean paralysis = target.hasBuff(ParalysisBuff.CATEGORY);
		if (paralysis) {
			return;
		}

		Hooks.AttackHookContext context = rawContext.as();
		final AttackContext attackContext = context.attackContext;
		if (attackContext.attacker != target) {
			return;
		}

		final StageMove move = attackContext.currentMove;
		if (move.attackerUsing == MoveType.MOVEMENT || move.vStats.length == 0) {
			return;
		}
		if (!move.mainType().equals(this.type)) {
			return;
		}

		attackContext.appendMoveRoll(target.createMoreRollWithAttackContext(attackContext, this));
	}

	public void beforeFoeReceiveBuff(Hooks.HookContext rawContext) {
		Hooks.BeforeFoeReceiveBuffContext context = rawContext.as();
		final FoeStageBuff otherBuff = context.otherBuff;

		if (otherBuff.is(CATEGORY) && otherBuff.is(type.name())) {
			context.abort();
			return;
		}

		// 检查是否潮湿. 如果有, 状态免疫失效
		if (target.hasBuff(WetBuff.CATEGORY)) {
			return;
		}

		switch (type) {
		case ELECTRIC: {
			if (otherBuff.is(ParalysisBuff.CATEGORY)) {
				context.abort();
			}
		} break;
		case FIRE: {
			if (otherBuff.is(BurnBuff.CATEGORY)) {
				context.abort();
			}
		} break;
		case SAND: {
			if (otherBuff.is(AcidBuff.CATEGORY)) {
				context.abort();
			}
		} break;
		case WATER: {
			if (otherBuff.is(WetBuff.CATEGORY)) {
				context.abort();
			}
		} break;
		case ICE: {
			if (otherBuff.is(FrostbiteBuff.CATEGORY)) {
				context.abort();
			}
		} break;
		case STEEL: {
			if (otherBuff.is(PoisonedBuff.CATEGORY)) {
				context.abort();
			}
		} break;
		}
	}

	@Override
	public boolean is(String category) {
		return CATEGORY.equals(category) || type.name().equals(category);
	}

	@Override
	public String getCategory() {
		return CATEGORY;
	}

	@Override
	public String toString() {
		return "属性:" + type;
	}
}
